04. 定义任务

定义任务

正如之前提到的,我们已经在 tasks/takeoff.py 中为你定义了起飞任务。你可以看看该任务,了解任务对象如何充当 ROS 和智能体代码之间的媒介。

  • __init__() :定义特定于任务的参数,包括状态(观察结果)空间和动作空间。
  • reset() :在每个阶段开始时初始化状态,将无人机扔到地面上。
  • update() :当出现新的状态时,ROS 会定期调用该方法。它在每个时间步将该状态传递给智能体,以及奖励值,获得一个动作,然后将该动作传回 ROS。

( ROS 然后将该动作发送给模拟环境,并获得下个状态以提供给 update()

任务的奖励函数定义如下:

reward = -min(abs(self.target_z - pose.position.z), 20.0)

reward = 0 表示匹配目标 z ,离得越远,则为负数,低达 -20 。如果四轴无人机达到目标高度,则获得额外的奖励,如果时间超时,则获得额外的惩罚。

运行任务

运行以下命令以使用默认参数启动 ROS(任务: 起飞 ,智能体: RandomPolicySearch ):

roslaunch quad_controller_rl rl_controller.launch

这相当于明确指定任务和智能体类名称:

roslaunch quad_controller_rl rl_controller.launch task:=Takeoff agent:=RandomPolicySearch

现在运行模拟器可执行文件。它应该会启动并显示“Connected to ROS”,并且左下角有绿色的点。

跌落的四轴飞行器!

你将发现,在每个阶段开始时,四轴飞行器从很矮的高度掉了下来,落到地面上,然后机翼开始转动。因为智能体一开始遵守的是完全随机的策略,你将看到飞行器到处歪斜着飞行!幸运的话,它可能会升到一定的高度。

示例智能体

我们仔细研究下在 agents/policy_search.py 中定义的示例智能体 RandomPolicySearch 。从外部调用了两个方法:

  • __init__() :初始化智能体,包括策略参数(随机设定)。它可以访问任务对象,因此可以检查状态空间和动作空间。
  • step() :在每个时间步用一个新的状态(观察结果)向量和奖励进行调用。它预期会返回一个属于任务的动作空间的动作。

在这种情况下, step() 方法只是累积每个时间步的奖励,并使用当前策略( act() 方法)返回一个动作。你也可以在此处存储经验元组或执行其他运算。在每个阶段结束时,它都会调用 learn() 方法,该方法会尝试(随机地)更新策略以完善策略,然后通过调用 reset_episode_vars() 为下个阶段做准备。

这个随机策略搜索方法对该项目中的任务来说并不足够,但是你依然可以使用该智能体作为模板并定义你自己的智能体。

你的智能体

要实现你自己的智能体,请在 agents/ 目录下创建一个新的 Python 文件。你可以根据你打算实现的算法/技巧命名它,例如 policy_gradients.py

现在创建一个继承自 BaseAgent 的类(或者你可以复制示例智能体中的部分,并根据需要加以修改)。例如,假设你要实现深度确定性策略梯度 (DDPG):

class DDPG(BaseAgent):
    ...

最后一个事项 - 为了运行智能体,你需要修改 agents/__init__.py 并在其中导入你的智能体类,例如:

from quad_controller_rl.agents.policy_gradients import DDPG

然后,在启动 ROS 时,你需要在命令行/终端上指定该类名称:

roslaunch quad_controller_rl rl_controller.launch agent:=DDPG

好了!现在你可以开始实现你的强化学习算法了!理想目标是训练智能体平稳地起飞。

四轴飞行器起飞了